package fr.teuteuf.runstickmanrun.map.tile;

import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.ChainShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;

import fr.teuteuf.runstickmanrun.Constants;

public class SolidBoxTile extends Tile {
	
	public static final byte TOP_BORDER    = 1;
	public static final byte RIGHT_BORDER  = 2;
	public static final byte BOTTOM_BORDER = 4;
	public static final byte LEFT_BORDER   = 8;
	
	private World world;
	private Body body;

	public SolidBoxTile(byte borders, int textureX, int textureY, int positionX, int positionY, World world) {
		super(textureX, textureY, positionX, positionY);
		
		this.world = world;
		
		BodyDef bodyDef = new BodyDef();
		bodyDef.position.set(new Vector2((positionX + TILE_SIZE/2) * Constants.WORLD_TO_BOX, (positionY + TILE_SIZE/2) * Constants.WORLD_TO_BOX));
		body = world.createBody(bodyDef);
		
		ChainShape shape = new ChainShape();
		Vector2 vertices[] = getVertices(borders);
		shape.createChain(vertices);
		
		body.createFixture(shape, 1f);
		body.setUserData(this);
		shape.dispose();
	}
	
	@Override
	public void destroy() {
		super.destroy();
		world.destroyBody(body);
	}
	
	public Vector2[] getVertices(byte borders) {
		Array<Vector2> vertices = new Array<Vector2>();
		Vector2 v0 = new Vector2(- (TILE_SIZE - 1) * Constants.WORLD_TO_BOX / 2, - (TILE_SIZE - 1) * Constants.WORLD_TO_BOX / 2);
		Vector2 v1 = new Vector2(- (TILE_SIZE - 1) * Constants.WORLD_TO_BOX / 2,   (TILE_SIZE - 1) * Constants.WORLD_TO_BOX / 2);
		Vector2 v2 = new Vector2(  (TILE_SIZE - 1) * Constants.WORLD_TO_BOX / 2,   (TILE_SIZE - 1) * Constants.WORLD_TO_BOX / 2);
		Vector2 v3 = new Vector2(  (TILE_SIZE - 1) * Constants.WORLD_TO_BOX / 2, - (TILE_SIZE - 1) * Constants.WORLD_TO_BOX / 2);
		int nbBorders = 0;
		
		if((borders & TOP_BORDER) != 0)
			nbBorders++;
		if((borders & RIGHT_BORDER) != 0)
			nbBorders++;
		if((borders & BOTTOM_BORDER) != 0)
			nbBorders++;
		if((borders & LEFT_BORDER) != 0)
			nbBorders++;

		if(nbBorders >= 3 || nbBorders == 2 && borders != 3 && borders != 6 && borders != 12 && borders != 9) {
			vertices.add(v1);
			vertices.add(v2);
			vertices.add(v0);
			vertices.add(v3);
		} else if(nbBorders == 2) {
			switch(borders) {
				case 3:
					vertices.add(v1);
					vertices.add(v2);
					vertices.add(v3);
					break;
				case 6:
					vertices.add(v2);
					vertices.add(v3);
					vertices.add(v0);
					break;
				case 12:
					vertices.add(v3);
					vertices.add(v0);
					vertices.add(v1);
					break;
				case 9:
					vertices.add(v0);
					vertices.add(v1);
					vertices.add(v2);
					break;
			}
		} else {
			if((borders & TOP_BORDER) != 0) {
				vertices.add(v1);
				vertices.add(v2);
			}
			if((borders & RIGHT_BORDER) != 0) {
				vertices.add(v2);
				vertices.add(v3);
			}
			if((borders & BOTTOM_BORDER) != 0) {
				vertices.add(v3);
				vertices.add(v0);
			}
			if((borders & LEFT_BORDER) != 0) {
				vertices.add(v0);
				vertices.add(v1);
			}
		}
		
		return vertices.toArray(Vector2.class);
	}

	public Body getBody() {
		return body;
	}
}
